package muxwstemplate

import (
	"sync"

	"github.com/gorilla/websocket"
)

type ClientGroupManager struct {
	ClientGroups map[string]map[*websocket.Conn]bool
	mutex        sync.RWMutex
}

func (c *ClientGroupManager) AddClientToGroup(groupName string, conn *websocket.Conn) {

	c.mutex.Lock()
	defer c.mutex.Unlock()

	if _, exist := c.ClientGroups[groupName]; !exist {
		c.ClientGroups[groupName] = make(map[*websocket.Conn]bool)
	}

	c.ClientGroups[groupName][conn] = true

	muxWSLogger.Infof("Connection has been add to the group [%s]，The count of the connection in the group : %d\n",
		groupName, len(c.ClientGroups[groupName]))
}
func (c *ClientGroupManager) RemoveClientFromGroup(groupName string, conn *websocket.Conn) {

	c.mutex.Lock()
	defer c.mutex.Unlock()

	if group, exist := c.ClientGroups[groupName]; exist {
		delete(group, conn)
		muxWSLogger.Infof("Connection remove from group [%s]，Avaliable connection count : %d\n", groupName, len(group))
		if len(group) == 0 {
			delete(c.ClientGroups, groupName)
			muxWSLogger.Errorf("Group [%s] already deleted.", groupName)
		}
	}
}

func (c *ClientGroupManager) GetClientGroup(groupName string) map[*websocket.Conn]bool {
	c.mutex.RLock()
	defer c.mutex.RUnlock()

	if group, exist := c.ClientGroups[groupName]; exist {
		return group
	}

	return nil
}

func (c *ClientGroupManager) GetClientGroupNames() []string {
	c.mutex.RLock()
	defer c.mutex.RUnlock()

	var groupNames []string

	for groupName := range c.ClientGroups {
		groupNames = append(groupNames, groupName)
	}

	return groupNames
}

func (c *ClientGroupManager) GetClientGroupNameCount(groupName string) int {

	c.mutex.RLock()
	defer c.mutex.RUnlock()

	return len(c.ClientGroups[groupName])
}

func (c *ClientGroupManager) GetClientGroupNamesCount() map[string]int {

	c.mutex.RLock()
	defer c.mutex.RUnlock()

	var groupNamesCount map[string]int
	for groupName, group := range c.ClientGroups {
		groupNamesCount[groupName] = len(group)
	}

	return groupNamesCount
}

func (c *ClientGroupManager) PushMessageToGroup(groupName string, message []byte) {

	c.mutex.RLock()
	defer c.mutex.RUnlock()

	if group, exist := c.ClientGroups[groupName]; exist {
		for conn := range group {
			err := conn.WriteMessage(websocket.TextMessage, message)
			if err != nil {
				muxWSLogger.Errorf("Message send to group[%s] failed error msg : %s ", groupName, err.Error())
				// 标记连接已断开，稍后清理
				go c.RemoveClientFromGroup(groupName, conn)
			}
		}
	} else {
		muxWSLogger.Errorf("Group[%s] not exists.", groupName)
	}
}
